package com.zenithmind.library.controller;

import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import com.zenithmind.library.pojo.dto.BookCreateDTO;
import com.zenithmind.library.pojo.dto.BookUpdateDTO;
import com.zenithmind.library.pojo.query.BookQuery;
import com.zenithmind.library.pojo.vo.BookDetailVO;
import com.zenithmind.library.pojo.vo.BookVO;
import com.zenithmind.library.service.BookService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 图书管理控制器
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@Slf4j
@RestController
@RequestMapping("/api/zenithMind/v1/books")
@RequiredArgsConstructor
@Tag(name = "图书管理", description = "图书信息的增删改查操作")
public class BookController {

    private final BookService bookService;

    @GetMapping
    @Operation(summary = "分页查询图书", description = "根据条件分页查询图书列表")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<PageResult<BookVO>> getBookPage(@Valid BookQuery query) {
        log.info("分页查询图书，查询条件：{}", query);
        PageResult<BookVO> result = bookService.getBookPage(query);
        return Result.success(result);
    }

    @GetMapping("/{id}")
    @Operation(summary = "查询图书详情", description = "根据ID查询图书详细信息")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<BookDetailVO> getBookDetail(
            @Parameter(description = "图书ID", required = true) @PathVariable String id) {
        log.info("查询图书详情，ID：{}", id);
        BookDetailVO result = bookService.getBookDetail(id);
        return Result.success(result);
    }

    @PostMapping
    @Operation(summary = "创建图书", description = "新增图书信息")
    @PreAuthorize("hasAuthority('library:book:create')")
    public Result<BookVO> createBook(@Valid @RequestBody BookCreateDTO createDTO) {
        log.info("创建图书，数据：{}", createDTO);
        return bookService.createBook(createDTO);
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新图书", description = "更新图书信息")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<BookVO> updateBook(
            @Parameter(description = "图书ID", required = true) @PathVariable String id,
            @Valid @RequestBody BookUpdateDTO updateDTO) {
        log.info("更新图书，ID：{}，数据：{}", id, updateDTO);
        return bookService.updateBook(id, updateDTO);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除图书", description = "根据ID删除图书")
    @PreAuthorize("hasAuthority('library:book:delete')")
    public Result<Void> deleteBook(
            @Parameter(description = "图书ID", required = true) @PathVariable String id) {
        log.info("删除图书，ID：{}", id);
        return bookService.deleteBook(id);
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除图书", description = "根据ID列表批量删除图书")
    @PreAuthorize("hasAuthority('library:book:delete')")
    public Result<Void> batchDeleteBooks(@RequestBody List<String> ids) {
        log.info("批量删除图书，IDs：{}", ids);
        return bookService.batchDeleteBooks(ids);
    }

    @PutMapping("/{id}/publish")
    @Operation(summary = "上架图书", description = "将图书设置为上架状态")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<Void> publishBook(
            @Parameter(description = "图书ID", required = true) @PathVariable String id) {
        log.info("上架图书，ID：{}", id);
        return bookService.publishBook(id);
    }

    @PutMapping("/{id}/unpublish")
    @Operation(summary = "下架图书", description = "将图书设置为下架状态")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<Void> unpublishBook(
            @Parameter(description = "图书ID", required = true) @PathVariable String id) {
        log.info("下架图书，ID：{}", id);
        return bookService.unpublishBook(id);
    }

    @PutMapping("/{id}/recommend")
    @Operation(summary = "推荐图书", description = "将图书设置为推荐状态")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<Void> recommendBook(
            @Parameter(description = "图书ID", required = true) @PathVariable String id) {
        log.info("推荐图书，ID：{}", id);
        return bookService.recommendBook(id);
    }

    @PutMapping("/{id}/unrecommend")
    @Operation(summary = "取消推荐图书", description = "取消图书的推荐状态")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<Void> unrecommendBook(
            @Parameter(description = "图书ID", required = true) @PathVariable String id) {
        log.info("取消推荐图书，ID：{}", id);
        return bookService.unrecommendBook(id);
    }

    @GetMapping("/isbn/{isbn}")
    @Operation(summary = "根据ISBN查询图书", description = "根据ISBN查询图书信息")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<BookVO> getBookByIsbn(
            @Parameter(description = "ISBN", required = true) @PathVariable String isbn) {
        log.info("根据ISBN查询图书，ISBN：{}", isbn);
        BookVO result = bookService.getBookByIsbn(isbn);
        return Result.success(result);
    }

    @GetMapping("/category/{categoryId}")
    @Operation(summary = "根据分类查询图书", description = "根据分类ID查询图书列表")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<PageResult<BookVO>> getBooksByCategory(
            @Parameter(description = "分类ID", required = true) @PathVariable String categoryId,
            @Valid BookQuery query) {
        log.info("根据分类查询图书，分类ID：{}，查询条件：{}", categoryId, query);
        PageResult<BookVO> result = bookService.getBooksByCategory(categoryId, query);
        return Result.success(result);
    }

    @GetMapping("/author/{authorId}")
    @Operation(summary = "根据作者查询图书", description = "根据作者ID查询图书列表")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<PageResult<BookVO>> getBooksByAuthor(
            @Parameter(description = "作者ID", required = true) @PathVariable String authorId,
            @Valid BookQuery query) {
        log.info("根据作者查询图书，作者ID：{}，查询条件：{}", authorId, query);
        PageResult<BookVO> result = bookService.getBooksByAuthor(authorId, query);
        return Result.success(result);
    }

    @GetMapping("/publisher/{publisherId}")
    @Operation(summary = "根据出版社查询图书", description = "根据出版社ID查询图书列表")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<PageResult<BookVO>> getBooksByPublisher(
            @Parameter(description = "出版社ID", required = true) @PathVariable String publisherId,
            @Valid BookQuery query) {
        log.info("根据出版社查询图书，出版社ID：{}，查询条件：{}", publisherId, query);
        PageResult<BookVO> result = bookService.getBooksByPublisher(publisherId, query);
        return Result.success(result);
    }

    @GetMapping("/search")
    @Operation(summary = "搜索图书", description = "根据关键词搜索图书")
    @PreAuthorize("hasAuthority('library:book:query')")
    public Result<PageResult<BookVO>> searchBooks(
            @Parameter(description = "搜索关键词", required = true) @RequestParam String keyword,
            @Valid BookQuery query) {
        log.info("搜索图书，关键词：{}，查询条件：{}", keyword, query);
        PageResult<BookVO> result = bookService.searchBooks(keyword, query);
        return Result.success(result);
    }

    @GetMapping("/recommended")
    @Operation(summary = "获取推荐图书", description = "获取推荐图书列表")
    public Result<PageResult<BookVO>> getRecommendedBooks(@Valid BookQuery query) {
        log.info("获取推荐图书，查询条件：{}", query);
        PageResult<BookVO> result = bookService.getRecommendedBooks(query);
        return Result.success(result);
    }

    @GetMapping("/new")
    @Operation(summary = "获取新书", description = "获取新书列表")
    public Result<PageResult<BookVO>> getNewBooks(@Valid BookQuery query) {
        log.info("获取新书，查询条件：{}", query);
        PageResult<BookVO> result = bookService.getNewBooks(query);
        return Result.success(result);
    }

    @GetMapping("/popular")
    @Operation(summary = "获取热门图书", description = "获取热门图书列表")
    public Result<PageResult<BookVO>> getPopularBooks(@Valid BookQuery query) {
        log.info("获取热门图书，查询条件：{}", query);
        PageResult<BookVO> result = bookService.getPopularBooks(query);
        return Result.success(result);
    }

    @PutMapping("/{id}/stock")
    @Operation(summary = "更新图书库存", description = "更新图书的库存信息")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<Void> updateBookStock(
            @Parameter(description = "图书ID", required = true) @PathVariable String id,
            @Parameter(description = "总库存数量", required = true) @RequestParam Integer totalCopies,
            @Parameter(description = "可借阅数量", required = true) @RequestParam Integer availableCopies) {
        log.info("更新图书库存，图书ID：{}，总库存：{}，可借阅库存：{}", id, totalCopies, availableCopies);
        return bookService.updateBookStock(id, totalCopies, availableCopies);
    }

    @PutMapping("/{id}/rating")
    @Operation(summary = "更新图书评分", description = "更新图书的评分信息")
    @PreAuthorize("hasAuthority('library:book:update')")
    public Result<Void> updateBookRating(
            @Parameter(description = "图书ID", required = true) @PathVariable String id,
            @Parameter(description = "评分", required = true) @RequestParam Double rating) {
        log.info("更新图书评分，图书ID：{}，评分：{}", id, rating);
        return bookService.updateBookRating(id, rating);
    }

    @PostMapping("/import")
    @Operation(summary = "导入图书数据", description = "批量导入图书数据")
    @PreAuthorize("hasAuthority('library:book:import')")
    public Result<String> importBooks(@RequestBody List<BookCreateDTO> books) {
        log.info("导入图书数据，数量：{}", books.size());
        return bookService.importBooks(books);
    }

    @GetMapping("/export")
    @Operation(summary = "导出图书数据", description = "导出图书数据到Excel文件")
    @PreAuthorize("hasAuthority('library:book:export')")
    public Result<String> exportBooks(@Valid BookQuery query) {
        log.info("导出图书数据，查询条件：{}", query);
        return bookService.exportBooks(query);
    }
}
